home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- * *
- * Copyright (C) 1996, Silicon Graphics, Inc. * * All Rights Reserved. *
- * *
- * The files in this subtree contain UNPUBLISHED PROPRIETARY SOURCE *
- * CODE of Silicon Graphics, Inc.; the contents of these files may *
- * not be disclosed to third parties, copied or duplicated in any *
- * form, in whole or in part, without the prior written permission *
- * of Silicon Graphics, Inc. *
- * *
- * RESTRICTED RIGHTS LEGEND: *
- * Use, duplication or disclosure by the Government is subject to *
- * restrictions as set forth in subdivision (c)(1)(ii) of the Rights in *
- * Technical Data and Computer Software clause at DFARS 252.227-7013, *
- * and/or in similar or successor clauses in the FAR, DOD or NASA FAR *
- * Supplement. Unpublished - rights reserved under the Copyright Laws *
- * of the United States. *
- * *
- * THIS SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, *
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY *
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. *
- * *
- * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, *
- * INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY *
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, *
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY *
- * THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *
- * PERFORMANCE OF THIS SOFTWARE. *
- **************************************************************************/
-
- /**************************************************************************
- * AUTHOR: Bob Shakib *
- * shakib@sgi.com *
- * (415) 933 6046 *
- **************************************************************************/
- /***************************************************************************
- * compile: cc -o roam roam.c -lGLw -lGL -lGLU -lXm -lXt -lX11 -limage -lm *
- * To run the demo: *
- * ./Roam
- * roam with button1 *
- * zoom with button2 *
- * rotate with button3 *
- * press "a" key for auto roam *
- * press "r" key to reset view *
- ****************************************************************************/
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <Xm/Frame.h>
- #include <X11/GLw/GLwMDrawA.h>
- #include <X11/keysym.h>
- #include <X11/Xutil.h>
- #include <GL/glx.h>
- #include <GL/glu.h>
- #include <sys/fcntl.h>
- #include "/usr/include/gl/image.h"
- #include "/usr/include/device.h"
-
- #define NUMTEX 16
- #define X_TEX 4
- #define Y_TEX 4
- #define WIDTH 4096
-
- typedef struct {
- GLuint compID;
- GLuint rectBaseX;
- GLuint rectBaseY;
- } tileStruct;
-
- typedef struct {
- GLuint textureID;
- tileStruct tile[2][2];
- } texStruct;
-
- typedef struct {
- texStruct tex[2][2];
- } listStruct;
-
- /* define a struct to keep image and widget information */
- typedef struct {
- Widget glxWidget; /* widget where images will be drawn */
- Widget frame;
- XtAppContext app; /* Xt application context */
- XtWorkProcId wpid; /* workproc id used for the rotate workproc */
- GLfloat theta; /* the angle by which the image is rotated */
- int direction; /* direction of image rotation */
- GLfloat incr; /* the increment to be added to the angle of rotation */
- GLfloat zoomFact;
- GLfloat factor;
- int winWidth; /* width of displayed image */
- int winHeight; /* height of displayed image */
- int mstate, omx, omy, mx, my; /* pointer locations and the button state */
- GLfloat x, y;
- listStruct list[3][3];
- } infoStruct;
-
-
-
- static void update_view_info(infoStruct* info);
- static void render_tex(infoStruct *info);
- static void readimage( char *file, char *buf);
-
- /* define the required atributes for the GLX drawable */
- static int attribs[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 4, None};
-
- /* define the resources for the GL widget */
- static String fallbackResources[] = {
- "*useSchemes: all",
- "*frame*shadowType: SHADOW_IN",
- NULL};
-
- static void readimage( char *file, char *buf)
- {
- int i,j;
- short rowbuf[4096];
-
- IMAGE *image;
- image = iopen(file,"r");
-
- for (i=0; i<image->ysize; i++)
- {
- getrow( image, rowbuf, i, 0 );
- for (j=0; j<image->xsize; j++)
- {
- *buf++ = (char) rowbuf[j];
- }
- }
- iclose(image);
- }
-
- /* workproc function that gets called repeatedly to increment the angle */
- /* and call the draw function */
- static Boolean
- roam_proc(XtPointer clientData)
- {
- infoStruct *info = (infoStruct *)clientData;
-
- info->theta += .05;
- info->theta = (info->theta < -360) ? info->theta=+360 :
- (info->theta > 360) ? info->theta=-360 :
- info->theta;
-
- if ((info->x < 6) && ((info->y == 1)||(info->y < 1)))
- {
- info->x += 0.002;
- render_tex(info);
- return False;
- }
- if ((info->y < 6) && (info->x > 6))
- {
- info->y += 0.002;
- render_tex(info);
- return False;
- }
- if ((info->x > 1) && (info->y > 6))
- {
- info->x -= 0.002;
- render_tex(info);
- return False;
- }
- if ((info->y > 1) && (info->x < 1))
- {
- info->y -= 0.002;
- render_tex(info);
- return False;
- }
- }
-
-
- /* callback to handle keyboard input */
- static void
- inputCB(Widget w, XtPointer client_data, XtPointer call)
- {
- char buffer[31];
- KeySym keysym;
- XEvent *event = ((GLwDrawingAreaCallbackStruct *) call)->event;
- /* GLwDrawingAreaCallbackStruct *call_data; */
- infoStruct *info = (infoStruct *) client_data;
-
- switch(event->type)
- {
- case KeyRelease:
- XLookupString(&event->xkey, buffer, 30, &keysym, NULL);
- switch(keysym)
- {
- /* exit the program if escape is pressed */
- case XK_Escape :
- exit(EXIT_SUCCESS);
- break;
- case XK_a :
- info->x = 1.0;
- info->y = 1.0;
- if (!info->wpid)
- {
- info->wpid = XtAppAddWorkProc(info->app, roam_proc, info);
- }
- break;
- case XK_s :
- if (info->wpid)
- {
- XtRemoveWorkProc(info->wpid);
- info->wpid = 0;
- }
- break;
- case XK_r :
- if (info->wpid)
- {
- XtRemoveWorkProc(info->wpid);
- info->wpid = 0;
- }
- info->x = 4.0;
- info->y = 4.0;
- info->theta = 0.0;
- info->zoomFact = 1.0;
- render_tex(info);
- break;
- case XK_Up :
- if (info->factor > 50)
- info->factor -= 10;
- break;
- case XK_Down :
- if (info->factor <1000)
- info->factor += 10;
- break;
- default: break;
- }
- break;
-
- case ButtonPress:
- if (info->wpid)
- {
- XtRemoveWorkProc(info->wpid);
- info->wpid = 0;
- }
- if (event->xbutton.button == Button1)
- {
- info->mstate = 1;
- info->mx = event->xbutton.x;
- info->my = event->xbutton.y;
- }
- else if (event->xbutton.button == Button2)
- {
- info->mstate = 2;
- info->mx = event->xbutton.x;
- info->my = event->xbutton.y;
- }
- else if (event->xbutton.button == Button3)
- {
- info->mstate = 3;
- info->mx = event->xbutton.x;
- info->my = event->xbutton.y;
- }
- break;
-
- case ButtonRelease:
- info->mstate = 0;
- break;
-
- case MotionNotify:
- if (info->mstate)
- {
- info->omx = info->mx;
- info->omy = info->my;
- info->mx = event->xbutton.x;
- info->my = event->xbutton.y;
- update_view_info(info);
- }
- break;
- }
- }
-
- /* this callback gets called everytime the window gets an expose or resize event */
- static void
- exposeCB(Widget w, XtPointer client_data, XtPointer call)
- {
- GLwDrawingAreaCallbackStruct *call_data;
- infoStruct *info;
-
- call_data = (GLwDrawingAreaCallbackStruct *) call;
- info = (infoStruct *) client_data;
- update_view_info(info);
- }
-
- static void
- update_view_info(infoStruct *info)
- {
- int dx = info->omx - info->mx;
- int dy = info->omy - info->my;
-
-
- if (info->mstate == 1) /*translate*/
- {
- info->x += (float)dx/info->factor;
- info->x = (info->x < 1.0) ? 1.0 : (info->x > 6.9) ? 6.9 : info->x;
- info->y -= (float)dy/info->factor;
- info->y = (info->y < 1.0) ? 1.0 : (info->y > 6.9) ? 6.9 : info->y;
- }
- else if (info->mstate == 2) /*zoom*/
- {
- info->zoomFact += (float)dy/150;
- info->zoomFact = (info->zoomFact < 1.0) ? 1.0 : ((info->zoomFact > 5.0) ? 5.0 : info->zoomFact);
- }
- else if (info->mstate == 3) /*rotate*/
- {
- info->theta += - (float)dy/5;
- info->theta = (info->theta < -360) ? info->theta = -360 :
- (info->theta > 360) ? info->theta= 360 :
- info->theta;
- }
-
- render_tex(info);
- }
-
-
- static void
- render_tex(infoStruct *info)
- {
-
- int lx, ly, tx, ty, cx, cy, baseX, baseY;
- /* Locate nearest four corners and call render textures on that corner */
- lx = (int)floor(info->x / 2. + .5) - 1;
- lx = (lx < 0) ? 0 : ((lx > (X_TEX - 1)) ? (X_TEX - 1) : lx); /* clamp [0, m - 1] */
- ly = (int)floor(info->y / 2. + .5) - 1;
- ly = (ly < 0) ? 0 : ((ly > (Y_TEX - 1)) ? (Y_TEX - 1) : ly); /* clamp [0, n - 1] */
-
- glPushMatrix(); /* Make sure that you're always in MODELVIEW here */
- glScalef(info->zoomFact, info->zoomFact, 1.0);
- glRotatef(-info->theta, 0., 0., 1.);
- glTranslatef(-info->x, -info->y, 0);
-
- for (tx=0; tx<2; tx++)
- for (ty=0; ty<2; ty++)
- {
- glBindTextureEXT(GL_TEXTURE_2D, info->list[lx][ly].tex[tx][ty].textureID);
- for (cx=0; cx<2; cx++)
- for (cy=0; cy<2; cy++)
- {
- glTexParameteri(GL_TEXTURE_2D, GL_QUAD_TEXTURE_SELECT_SGIS,
- info->list[lx][ly].tex[tx][ty].tile[cx][cy].compID);
- /* map the texture one component at a time */
- /* texture coordinates go from 1/1024 to 511/512 */
- baseX = info->list[lx][ly].tex[tx][ty].tile[cx][cy].rectBaseX;
- baseY = info->list[lx][ly].tex[tx][ty].tile[cx][cy].rectBaseY;
- glBegin(GL_QUADS);
- glTexCoord2f(0.0009765625, 0.0009765625);
- glVertex2f(baseX, baseY);
- glTexCoord2f(0.99804688, 0.0009765625);
- glVertex2i(baseX + 1, baseY);
- glTexCoord2f(0.99804688, 0.99804688);
- glVertex2i(baseX + 1, baseY + 1);
- glTexCoord2f(0.0009765625, 0.99804688);
- glVertex2i(baseX, baseY + 1);
- glEnd();
- }
- }
- glPopMatrix();
- glXSwapBuffers(XtDisplay(info->glxWidget), XtWindow(info->glxWidget));
- }
-
- main(int argc, char *argv[])
- {
-
- infoStruct *info;
- Display *dpy;
- XVisualInfo *visinfo;
- Widget toplevel;
- GLXContext glxcontext;
- XtAppContext app;
- GLubyte *srcImg;
- GLubyte *base1, *base2, *base3, *base4;
- GLubyte *dst, *dstPtr;
- GLubyte *src1, *src2, *src3, *src4;
- GLint i, j, k, m, n, p, tx, ty, cx, cy, lx, ly;
- GLuint texCount, xsize, ysize;
- GLuint textures[4][4];
- GLuint *texNames;
- GLuint rectBaseX;
- GLuint rectBaseY;
- IMAGE *image;
-
-
- /* Allocate the infoStruct space */
- info = (infoStruct*) calloc(1, sizeof(infoStruct));
-
- /* set the angle of rotation to zero since the image is still until user */
- /* starts the rotation */
- info->theta = 0.0;
- /* set the initial increment to a low value to get a smooth rotation */
- info->incr = 0.2;
- /* creat ea top level shell for the application */
- info->x = 4.0;
- info->y = 4.0;
- info->zoomFact = 1.0;
- info->factor = 400;
-
- toplevel = XtOpenApplication(&info->app, "rotate", NULL, 0, &argc, argv,
- fallbackResources, applicationShellWidgetClass,
- NULL, 0);
-
- /* get a display going */
- dpy = XtDisplay(toplevel);
- /* create a frame widget to put the gl widget in */
- info->frame = XmCreateFrame(toplevel, "frame", NULL, 0);
- XtManageChild(info->frame);
-
- /* specify visual directly */
- if (!(visinfo = glXChooseVisual(dpy, DefaultScreen(dpy), attribs)))
- XtAppError(info->app, "no suitable RGB visual");
- /* create the gl widget for drawing */
- info->glxWidget = XtVaCreateManagedWidget("glxwidget", glwMDrawingAreaWidgetClass,
- info->frame, GLwNvisualInfo, visinfo, NULL);
- /* set the initial width and height of the GL widget to be the width and height */
- /* of the loaded image */
- XtVaSetValues(info->glxWidget, XmNwidth, 950, NULL);
- XtVaSetValues(info->glxWidget, XmNheight, 950, NULL);
-
- /* add the input handling and expose callbacks */
- XtAddCallback(info->glxWidget, GLwNexposeCallback, exposeCB, info);
- XtAddCallback(info->glxWidget, GLwNinputCallback, inputCB, info);
-
- XtRealizeWidget(toplevel);
-
- /* create a context */
- glxcontext = glXCreateContext(dpy, visinfo, 0, GL_TRUE);
- /* make the context current with the gl widget */
- GLwDrawingAreaMakeCurrent(info->glxWidget, glxcontext);
-
-
- glClearColor(0.0, 0.0, 0.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
- glXSwapBuffers(XtDisplay(info->glxWidget), XtWindow(info->glxWidget));
-
- srcImg = (unsigned char *)calloc(1, 4096*4096);
-
- readimage( "./data/berlin.bw", srcImg);
-
-
- glViewport(0, 0, 950, 950);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(-0.70710678, 0.70710678, -0.70710678, 0.70710678, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glEnable(GL_TEXTURE_2D);
-
- /* set up the texture parameters and load the texture */
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- /* split up the image data into XSIZE*YSIZE texture tiles which are
- grouped in 4 and interleaved */
- dst = (GLubyte*)calloc(1, 1024*1024);
- texCount = 0;
- texNames = malloc(NUMTEX*sizeof(GLuint));
- glGenTexturesEXT(NUMTEX, texNames);
-
- for (p=0, base1=srcImg; p<2; p++, base1+=WIDTH*2044)
- for (n=0, base2=base1; n<2; n++, base2+=2044)
- for (m=0, base3=base2; m<2; m++, base3+=WIDTH*1022)
- for (k=0, base4=base3; k<2; k++,base4+=1022)
- {
- /* reposition the src and destination pointers */
- src1=base4;
- src2=src1+511;
- src3=base4+(511*WIDTH);
- src4=src3+511;
- dstPtr=(GLubyte*)dst;
-
- for (j=0;j<512;j++)
- {
- for (i=0;i<512;i++)
- {
- *dstPtr++ = *src1++;
- *dstPtr++ = *src2++;
- *dstPtr++ = *src3++;
- *dstPtr++ = *src4++;
- }
- src1 += 4096 - 512;
- src2 += 4096 - 512;
- src3 += 4096 - 512;
- src4 += 4096 - 512;
- }
- glBindTextureEXT(GL_TEXTURE_2D, texNames[texCount++]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_QUAD_LUMINANCE8_SGIS, 512, 512, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, dst);
- }
- free(dst);
-
- /* Fill in textures array with jittered texture names */
- textures[0][0] = 1;
- textures[0][1] = 3;
- textures[0][2] = 9;
- textures[0][3] = 11;
- textures[1][0] = 2;
- textures[1][1] = 4;
- textures[1][2] = 10;
- textures[1][3] = 12;
- textures[2][0] = 5;
- textures[2][1] = 7;
- textures[2][2] = 13;
- textures[2][3] = 15;
- textures[3][0] = 6;
- textures[3][1] = 8;
- textures[3][2] = 14;
- textures[3][3] = 16;
-
- /* initialize the central cross-sections with surrounding 4 textures and subtiles */
- for (j = 0; j < X_TEX - 1; j++)
- for (i = 0; i < Y_TEX - 1; i++)
- for (tx = 0; tx < 2; tx++)
- for (ty = 0; ty < 2; ty++)
- {
- info->list[j][i].tex[tx][ty].textureID = textures[j + ty][i + tx];
- for (cx = 0; cx < 2; cx++)
- for (cy = 0; cy < 2; cy++)
- {
- info->list[j][i].tex[tx][ty].tile[cx][cy].compID = 2 * cx + cy;
- info->list[j][i].tex[tx][ty].tile[cx][cy].rectBaseX = 2 * (j + ty) + cy;
- info->list[j][i].tex[tx][ty].tile[cx][cy].rectBaseY = 2 * (i + tx) + cx;
- }
- }
-
- /* start the Xt main loop */
- XtAppMainLoop(info->app);
- }
-
-